package com.alogic.textfilter.impl;

import com.alogic.commonmark.HtmlRenderer;
import com.alogic.commonmark.image.ImageAttributesExtension;
import com.alogic.textfilter.TextFilter;
import com.anysoft.util.*;
import org.commonmark.Extension;
import org.commonmark.node.*;
import org.commonmark.parser.Parser;
import org.commonmark.ext.gfm.tables.TablesExtension;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import java.util.ArrayList;
import java.util.List;

/**
 * Markdown文档渲染
 *
 * @since 1.6.13.11 [20200901 duanyy] <br>
 *
 * @version 1.6.13.16 [20200910 duanyy] <br>
 * - 增加htmlEscape参数 <br>
 *
 * @version 1.6.13.22 [20201026 duanyy] <br>
 * - 增加缓存filter结果的功能
 */
public class MdRenderer extends TextFilter.Abstract {
    protected Parser.Builder parserBuilder = Parser.builder();
    protected HtmlRenderer.Builder htmlRenderer = HtmlRenderer.builder();

    protected ThreadLocal<Parser> parser = new ThreadLocal<Parser>(){
        protected Parser initialValue() {
            return parserBuilder.build();
        };
    };

    protected ThreadLocal<HtmlRenderer> renderer = new ThreadLocal<HtmlRenderer>(){
        protected HtmlRenderer initialValue() {
            return htmlRenderer.build0();
        };
    };

    protected List<Extension> extensions = new ArrayList<Extension>();

    @Override
    public void onConfigure(Element e, Properties p) {
        extensions.add(TablesExtension.create());
        extensions.add(ImageAttributesExtension.create());

        NodeList nodeList = XmlTools.getNodeListByPath(e,"extension");
        Factory<Extension> f = new Factory<Extension>();
        for (int i = 0 ; i < nodeList.getLength(); i ++){
            org.w3c.dom.Node node = nodeList.item(i);
            if (org.w3c.dom.Node.ELEMENT_NODE != node.getNodeType()){
                continue;
            }
            Element elem = (Element)node;
            try {
                Extension extension = f.newInstance(elem,p,"module");
                if (extension != null){
                    extensions.add(extension);
                }
            }catch (Exception ex){
                LOG.warn("Failed to create common mark extension:" + XmlTools.node2String(elem));
            }
        }
        parserBuilder.extensions(extensions);
        htmlRenderer.extensions(extensions);
        htmlRenderer.escapeHtml(PropertiesConstants.getBoolean(p,"htmlEscaped",false,true));
    }

    @Override
    public String onFilter(String text, Properties ctx) {
        Node document = parser.get().parse(text);
        return renderer.get().render(document,ctx);
    }
}
